package com.example.myapplication.function.musicmode

/**
 * 1. 核心音乐理论系统
 */
class ScaleTheorySystem {
    
    // 音阶类型定义
    enum class ScaleType {
        MAJOR,              // 大调音阶
        NATURAL_MINOR,      // 自然小调
        HARMONIC_MINOR,     // 和声小调
        MELODIC_MINOR,      // 旋律小调
        PENTATONIC_MAJOR,   // 大调五声音阶
        PENTATONIC_MINOR,   // 小调五声音阶
        DORIAN,             // 多利亚调式
        PHRYGIAN,           // 弗利几亚调式
        LYDIAN,             // 利底亚调式
        MIXOLYDIAN,         // 混合利底亚调式
        LOCRIAN             // 洛克里亚调式
    }
    
    data class Scale(
        val root: String,       // 根音 (C, C#, D, etc.)
        val scaleType: ScaleType,
        val intervals: List<Int>, // 相对于根音的半音数
        val noteNames: List<String> // 音阶包含的音符
    ) {
        fun getScaleName(): String {
            return "$root ${getScaleTypeName(scaleType)}"
        }
    }
    
    data class KeyDetectionResult(
        val scale: Scale,
        val confidence: Double,
        val matchedNotes: List<String>,
        val totalNotes: Int
    )
    
    companion object {
        // 定义各种音阶的音程结构 (半音数)
        val SCALE_INTERVALS = mapOf(
            ScaleType.MAJOR to listOf(0, 2, 4, 5, 7, 9, 11),
            ScaleType.NATURAL_MINOR to listOf(0, 2, 3, 5, 7, 8, 10),
            ScaleType.HARMONIC_MINOR to listOf(0, 2, 3, 5, 7, 8, 11),
            ScaleType.MELODIC_MINOR to listOf(0, 2, 3, 5, 7, 9, 11),
            ScaleType.PENTATONIC_MAJOR to listOf(0, 2, 4, 7, 9),
            ScaleType.PENTATONIC_MINOR to listOf(0, 3, 5, 7, 10),
            ScaleType.DORIAN to listOf(0, 2, 3, 5, 7, 9, 10),
            ScaleType.PHRYGIAN to listOf(0, 1, 3, 5, 7, 8, 10),
            ScaleType.LYDIAN to listOf(0, 2, 4, 6, 7, 9, 11),
            ScaleType.MIXOLYDIAN to listOf(0, 2, 4, 5, 7, 9, 10),
            ScaleType.LOCRIAN to listOf(0, 1, 3, 5, 6, 8, 10)
        )
        
        val NOTE_NAMES = listOf("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")
        
        fun getScaleTypeName(scaleType: ScaleType): String {
            return when (scaleType) {
                ScaleType.MAJOR -> "大调"
                ScaleType.NATURAL_MINOR -> "自然小调"
                ScaleType.HARMONIC_MINOR -> "和声小调"
                ScaleType.MELODIC_MINOR -> "旋律小调"
                ScaleType.PENTATONIC_MAJOR -> "大调五声"
                ScaleType.PENTATONIC_MINOR -> "小调五声"
                ScaleType.DORIAN -> "多利亚调式"
                ScaleType.PHRYGIAN -> "弗利几亚调式"
                ScaleType.LYDIAN -> "利底亚调式"
                ScaleType.MIXOLYDIAN -> "混合利底亚调式"
                ScaleType.LOCRIAN -> "洛克里亚调式"
            }
        }
    }
    
    // 生成所有可能的音阶
    fun generateAllScales(): List<Scale> {
        val scales = mutableListOf<Scale>()
        
        NOTE_NAMES.forEach { root ->
            ScaleType.values().forEach { scaleType ->
                val intervals = SCALE_INTERVALS[scaleType] ?: return@forEach
                val noteNames = intervals.map { interval ->
                    val noteIndex = (NOTE_NAMES.indexOf(root) + interval) % 12
                    NOTE_NAMES[noteIndex]
                }
                scales.add(Scale(root, scaleType, intervals, noteNames))
            }
        }
        
        return scales
    }
    
    // 计算音符在音阶中的匹配度
    fun calculateScaleMatch(notes: List<String>, scale: Scale): Double {
        if (notes.isEmpty()) return 0.0
        
        val matchedNotes = notes.count { it in scale.noteNames }
        return matchedNotes.toDouble() / notes.size
    }
    
    // 检测最可能的调式
    fun detectKey(notes: List<String>): List<KeyDetectionResult> {
        val allScales = generateAllScales()
        val results = mutableListOf<KeyDetectionResult>()
        
        allScales.forEach { scale ->
            val confidence = calculateScaleMatch(notes, scale)
            val matchedNotes = notes.filter { it in scale.noteNames }
            
            if (confidence > 0.3) { // 只考虑匹配度30%以上的音阶
                results.add(KeyDetectionResult(scale, confidence, matchedNotes, notes.size))
            }
        }
        
        // 按置信度排序
        return results.sortedByDescending { it.confidence }
    }
}